<?php
/**
 * 门锁远程控制
 **/
namespace Home\Controller;
use Think\Controller;

class LockcmdController extends Controller {
	protected $webservice = 'http://114.119.5.137:1001/NLockWebService.asmx?wsdl'; //接口地址
	
	protected $opentype = array(
		'40' => '卡开锁',
		'41' => '密码开锁',
		'42' => '机械钥匙开锁',
		'43' => '关锁',
		'44' => '非法卡',
		'45' => '非法密码',
		'46' => '破门',
		'4D' => '取电成功',
		'4E' => '断电成功',
	);
	public function __construct() {
        parent::__construct();
		
		//判断是否登陆
		if(session('user_id')){ //已登陆
			
		}else{ //未登陆，跳转道登陆界面
			$this->redirect("index/index");
		}
    }
	
	/**
	 * 远程控制
	 *
	 **/
	public function cmd(){
		if(IS_GET){
			$page = I('get.page') ? (int)I('get.page') : 1;
			$ajax = I('get.ajax') ? (int)I('get.ajax') : 0;
			
			$count = D('Lockcmd')->getLockcmdLogListCount();
			//用户列表
			$list = D('Lockcmd')->getLockcmdLogList($page);
			
			$this->assign('list', $list);
			$this->assign('count', $count);
			$this->assign('page', $page);
			
			//判断请求方式
			if(!$ajax){
				$this->display('cmd');
			}else{
				$this->display('cmd_list', 'utf-8', 'html');
			}
		}else if(IS_POST){
			$cmd = I('post.cmd') ? trim(I('post.cmd')) : '';
			$remark = I('post.remark') ? trim(I('post.remark')) : '';
			$btime = I('post.btime') ? trim(I('post.btime')) : '';
			$etime = I('post.etime') ? trim(I('post.etime')) : '';
			//获取房间号
			$room_number = I('post.room_number') ? trim(I('post.room_number')) : '';
			if(!empty($room_number)){
				$lock = D('Lock')->getLockInfoByRoomNumbers($room_number);
				if(is_array($lock) && count($lock)){
					
				}else{
					$this->ajaxReturn('请不存在房间号与锁的关系','json');
				}
			}else{
				$this->ajaxReturn('请输入房间号', 'json');
			}
			
			//组装日志
			$log = array(
				'room_number' => $room_number,
				'user_id' => session('user_id'),
				'nickname' => session('nickname'),
				'lock_id' => $lock['cmd_id'],
				'network_nums' => $lock['network_nums'],
				'cmd_time' => time(),
				'b_time' => $btime,
				'e_time' => $etime
			);
			
			switch($cmd){
				case '002':
					//获取员工信息
					$staff = D('Staff')->getStaffInfoByName($remark);
					if(is_array($staff) && count($staff)){
						//$lasttime = date('H:i:s', time());
						$data['param3'] = $this->strrevtostr($staff['card_udid']); //str_pad($staff['card_udid'], 18, 'F'); //身份证UDID
						if(empty($btime) || empty($etime)){
							$this->ajaxReturn('请选择开始时间或结束时间');
						}else{
							$data['param4'] = $btime;
							$data['param5'] = $etime;
						}
						
						$param['JsonStr'] = "{result:0,events:[{event:002,param1:'{$lock['network_nums']}',param2:'{$lock['cmd_id']}',param3:'{$data['param3']}',param4:'{$data['param4']}',param5:'{$data['param5']}',param6:'111111111111111111111111',param7:'11111111'}]}";
					}else{
						$this->ajaxReturn('不存在该员工', 'json');
					}
					
					$log['cmd'] = '发送身份证ID';
					$log['param'] = '姓名：'. $remark .' ID：'. $staff['card_udid'];
					$log['b_time'] = $data['param4'];
					$log['e_time'] = $data['param5'];
					$log['cmd_key'] = '002';
				break;
				case '003': // 89 67 45 23 F1 FF FF FF FF
					//获取房卡信息
					$card = D('Roomcard')->getRoomCardInfoByCard($remark);
					if(is_array($card) && count($card)){
						$data['param3'] = str_pad($card['card_udid'], 18, 'F'); //身份证UDID
						if(empty($btime) || empty($etime)){
							$this->ajaxReturn('请选择开始时间或结束时间');
						}else{
							$data['param4'] = $btime;
							$data['param5'] = $etime;
						}
						
						$param['JsonStr'] = "{result:0,events:[{event:003,param1:'{$lock['network_nums']}',param2:'{$lock['cmd_id']}',param3:'{$data['param3']}',param4:'{$data['param4']}',param5:'{$data['param5']}',param6:'111111111111111111111111',param7:'11111111'}]}";
					}else{
						$this->ajaxReturn('不存在该房卡', 'json');
					}
					
					$log['cmd'] = '发送IC卡ID';
					$log['param'] = '房卡号：'. $remark;
					$log['b_time'] = $data['param4'];
					$log['e_time'] = $data['param5'];
					$log['cmd_key'] = '003';
				break;
				case '004':
					//设置密码
					if(!empty($remark) && is_numeric($remark)){
						$data['param3'] = $this->strrevtostr($remark); //str_pad($remark, 18, 'F');//密码 78563412FFFFFFFFFF'
						if(empty($btime) || empty($etime)){
							$this->ajaxReturn('请选择开始时间或结束时间');
						}else{
							$data['param4'] = $btime;
							$data['param5'] = $etime;
						}
						
						$param['JsonStr'] = "{result:0,events:[{event:004,param1:'{$lock['network_nums']}',param2:'{$lock['cmd_id']}',param3:'{$data['param3']}',param4:'{$data['param4']}',param5:'{$data['param5']}',param6:'111111111111111111111111',param7:'11111111'}]}";
					}else{
						$this->ajaxReturn('请输入数字密码', 'json');
					}
					
					$log['cmd'] = '发送密码';
					$log['param'] = '密码信息：'. $remark;
					$log['b_time'] = $data['param4'];
					$log['e_time'] = $data['param5'];
					$log['cmd_key'] = '004';
				break;
				case '005':
					//获取员工信息
					$staff = D('Staff')->getStaffInfoByName($remark);
					if(is_array($staff) && count($staff)){
						$data['param3'] = $this->strrevtostr($staff['card_udid']); //str_pad($staff['card_udid'], 18, 'F'); //身份证UDID
					}else{
						$this->ajaxReturn('不存在该员工', 'json');
					}
					
					$param['JsonStr'] = "{result:0,events:[{event:005,param1:'{$lock['network_nums']}',param2:'{$lock['cmd_id']}',param3:'{$data['param3']}'}]}";
					
					$log['cmd'] = '取消身份证ID';
					$log['param'] = '姓名：'. $remark .' ID：'. $staff['card_udid'];
					$log['b_time'] = $log['e_time'] = '---';
					$log['cmd_key'] = '005';
				break;
				case '006':
					//获取房卡信息
					$card = D('Roomcard')->getRoomCardInfoByCard($remark);
					if(is_array($card) && count($card)){
						$data['param3'] = str_pad($card['card_udid'], 18, 'F'); //身份证UDID
					}else{
						$this->ajaxReturn('不存在该房卡', 'json');
					}
					
					$param['JsonStr'] = "{result:0,events:[{event:006,param1:'{$lock['network_nums']}',param2:'{$lock['cmd_id']}',param3:'{$data['param3']}'}]}";
					
					$log['cmd'] = '取消IC卡ID';
					$log['param'] = '房卡号：'. $remark;
					$log['b_time'] = $log['e_time'] = '---';
					$log['cmd_key'] = '006';
				break;
				case '007':
					//取消密码
					if(!empty($remark) && is_numeric($remark)){
						$data['param3'] = $this->strrevtostr($remark); //str_pad($remark, 18, 'F'); //密码
					}else{
						$this->ajaxReturn('请输入数字密码', 'json');
					}
					
					$param['JsonStr'] = "{result:0,events:[{event:007,param1:'{$lock['network_nums']}',param2:'{$lock['cmd_id']}',param3:'{$data['param3']}'}]}";
					
					$log['cmd'] = '取消密码';
					$log['param'] = '密码信息：'. $remark;
					$log['b_time'] = $log['e_time'] = '---';
					$log['cmd_key'] = '007';
				break;
				case '008':
					$log['cmd'] = '删除所有用户';
					$log['param'] = '---';
					$log['b_time'] = $log['e_time'] = '---';
					$log['cmd_key'] = '008';
					$param['JsonStr'] = "{result:0,events:[{event:008,param1:'{$lock['network_nums']}',param2:'{$lock['cmd_id']}'}]}";
				break;
			}
			
			$list = $this->CallSoapWebService('GPRSCMD', $param);
			
			//判断结果
			$rows = $list['events'][0]['event'];
			$log['result'] = $rows ? 0 : 1;
			//判断结果
			$row = D('Lockcmd')->addLockcmdLog($log);
			if($log['result']){
				$this->ajaxReturn('授权成功', 'json');
			}else{
				$this->ajaxReturn('授权失败', 'json');
			}
		}
	}
	
	/**
	 * 导出控制日志
	 **/
	public function cmdexcel(){
		$list = D('Lockcmd')->getLockcmdLogListAll();
		$xlsCell = array(
			array('room_number', '房间号'),
			array('network_nums','网管编号'),
			array('lock_id','门锁ID'),
			array('nickname','操作人'),
			array('cmd','操作指令'),
			array('param','参数'),
			array('cmd_time','操作时间'),
			array('b_time','开始时间'),
			array('e_time','结束时间'),
			array('result','操作结果'),
		);
		if(is_array($list)){
			foreach($list as $ls){
				$excelData[] = array(
					'room_number' => $ls['room_number'],
					'network_nums' => $ls['network_nums'],
					'lock_id' => $ls['lock_id'],
					'nickname' => $ls['nickname'],
					'cmd' => $ls['cmd'],
					'param' => $ls['param'],
					'cmd_time' => date('Y-m-d H:i', $ls['cmd_time']),
					'b_time' => $ls['b_time'],
					'e_time' => $ls['e_time'],
					'result' => $ls['result'] == 1 ? '成功' : '失败',
				);
			}
		}
		//执行
		D('Excel')->exportExcel('远程控制日志表', $xlsCell, $excelData, '远程控制日志表_'.date('Y-m-d H:i'));	
	}
	
	/**
	 * 开锁记录
	 **/
	public function open(){
		$page = I('get.page') ? (int)I('get.page') : 1;
		$ajax = I('get.ajax') ? (int)I('get.ajax') : 0;
		//组装参数
		$room_number = I('get.room_number') ? trim(I('get.room_number')) : '';
		if(!empty($room_number)){
			$lock = D('Lock')->getLockInfoByRoomNumbers($room_number);
			$where['user_num'] = $lock['network_barcode'];
			$where['lock_no'] = $lock['cmd_id'];
			
			$param['room_number'] = $room_number;
		}
		
		$begin_time = I('get.begin_time') ? trim(I('get.begin_time')) : '';
		$end_time = I('get.end_time') ? trim(I('get.end_time')) : '';
		
		//判断时间参数
		if(!empty($begin_time) && empty($end_time)){
			$where['open_time'] = array('gt', strtotime($begin_time.' 00:00:00'));
		}else if(!empty($begin_time) && !empty($end_time)){
			$where['open_time'] = array('between', array(strtotime($begin_time.' 00:00:00'), strtotime($end_time.' 23:59:59')));
		}
		
		$count = D('Lockopen')->getLockopenLogListCount($where);
		//用户列表
		$list = D('Lockopen')->getLockopenLogList($page, $where);
		
		$this->assign('list', $list);
		$this->assign('count', $count);
		$this->assign('page', $page);
		
		//判断请求方式
		if(!$ajax){
			$this->display('open');
		}else{
			if(is_array($param) && count($param)){
				$this->assign('param', json_encode($param));
			}
			$this->display('open_list', 'utf-8', 'html');
		}
	}
	
	/**
	 * 导出Excel
	 **/
	public function openexcel(){
		//组装参数
		$room_number = I('get.room_number') ? trim(I('get.room_number')) : '';
		if(!empty($room_number)){
			$lock = D('Lock')->getLockInfoByRoomNumbers($room_number);
			$where['user_num'] = $lock['network_barcode'];
			$where['lock_no'] = $lock['cmd_id'];
		}
		
		$begin_time = I('get.begin_time') ? trim(I('get.begin_time')) : '';
		$end_time = I('get.end_time') ? trim(I('get.end_time')) : '';
		
		//判断时间参数
		if(!empty($begin_time) && empty($end_time)){
			$where['open_time'] = array('gt', strtotime($begin_time.' 00:00:00'));
		}else if(!empty($begin_time) && !empty($end_time)){
			$where['open_time'] = array('between', array(strtotime($begin_time.' 00:00:00'), strtotime($end_time.' 23:59:59')));
		}
		//日志列表
		$list = D('Lockopen')->getLockopenLogListAll($where);
		$xlsCell = array(
			array('j_id', '记录ID'),
			array('network_nums','设备号'),
			array('lock_no','门锁ID'),
			array('room_number','房间号'),
			array('title','记录类型'),
			array('open_num','开门方式'),
			array('open_time','开门时间')
		);
		if(is_array($list)){
			foreach($list as $ls){
				$excelData[] = array(
					'j_id' => $ls['j_id'],
					'network_nums' => $ls['network_nums'],
					'lock_no' => $ls['lock_no'],
					'room_number' => $ls['room_number'],
					'title' => $ls['title'],
					'open_num' => $ls['open_num'],
					'open_time' => date('Y-m-d H:i', $ls['open_time'])
				);
			}
		}
		//执行
		D('Excel')->exportExcel('开锁信息表', $xlsCell, $excelData, '门锁开启记录_'.date('Y-m-d H:i'));	
	}
	
	/**
	 * 分配记录
	 *
	 **/
	public function assigns(){
		if(IS_GET){
			$page = I('get.page') ? (int)I('get.page') : 1;
			$ajax = I('get.ajax') ? (int)I('get.ajax') : 0;
			
			$where['cmd_key'] = array('exp', "in('002','003','004','005','006', '007')");
			$where['result'] = 1;
			
			//获取房间号
			$room_number = I('get.room_number') ? trim(I('get.room_number')) : '';
			
			if(!empty($room_number)){
				$where['room_number'] = $room_number;
			}
			
			$count = D('Lockcmd')->getLockcmdLogListCount($where);
			//用户列表
			$list = D('Lockcmd')->getLockcmdLogList($page, $where);
			
			$this->assign('list', $list);
			$this->assign('count', $count);
			$this->assign('page', $page);
			
			//判断请求方式
			if(!$ajax){
				$this->display('assigns');
			}else{
				$this->assign('param', json_encode(array('room_number' => $room_number)));
				$this->display('cmd_list', 'utf-8', 'html');
			}
		}
	}
	
	/**
	 * 导出控制日志
	 **/
	public function assignsexcel(){
		$where['cmd_key'] = array('exp', "in('002','003','004','005','006', '007')");
		$where['result'] = 1;
		
		//获取房间号
		$room_number = I('get.room_number') ? trim(I('get.room_number')) : '';
		
		if(!empty($room_number)){
			$where['room_number'] = $room_number;
		}
		
		//用户列表
		$list = D('Lockcmd')->getLockcmdLogListAll($where);
		
		$xlsCell = array(
			array('room_number', '房间号'),
			array('network_nums','网管编号'),
			array('lock_id','门锁ID'),
			array('nickname','操作人'),
			array('cmd','操作指令'),
			array('param','参数'),
			array('cmd_time','操作时间'),
			array('b_time','开始时间'),
			array('e_time','结束时间'),
			array('result','操作结果'),
		);
		if(is_array($list)){
			foreach($list as $ls){
				$excelData[] = array(
					'room_number' => $ls['room_number'],
					'network_nums' => $ls['network_nums'],
					'lock_id' => $ls['lock_id'],
					'nickname' => $ls['nickname'],
					'cmd' => $ls['cmd'],
					'param' => $ls['param'],
					'cmd_time' => date('Y-m-d H:i', $ls['cmd_time']),
					'b_time' => $ls['b_time'],
					'e_time' => $ls['e_time'],
					'result' => $ls['result'] == 1 ? '成功' : '失败',
				);
			}
		}
		//执行
		D('Excel')->exportExcel('门锁电子钥匙分配记录', $xlsCell, $excelData, '门锁电子钥匙分配记录_'.date('Y-m-d H:i'));	
	}
	
	/**
	 * 异步获取设备日志
	 * 
	 **/
	public function ajaxlog(){
		$room_number = I('get.room_number') ? trim(I('get.room_number')) : '';
		if(!empty($room_number)){
			$lock = D('Lock')->getLockInfoByRoomNumbers($room_number);
			//组装请求参数
			$param['devicenum'] = $lock['network_nums'];
			//获取最大日志ID 
			$maxID = D('Lockopen')->getMaxJidByNetworkNums($lock['network_barcode']);
			$param['StartID'] = empty($maxID) ? 0 : $maxID;
			//获取结果
			$list = $this->CallSoapWebService('GetsOpenRecord', $param);
			//解析数据
			if(is_array($list) && count($list) && $list['result']){
				foreach($list['parameters'] as $ls){
					$data[] = array(
						'parameter' => $ls['parameter'],
						'j_id' => $ls['j_id'],
						'user_num' => $ls['user_num'],
						'lock_no' => (int)$ls['lock_no'],
						'open_type' => $ls['open_type'],
						'title' => $this->opentype[$ls['open_type']],
						'open_num' => dechex($ls['open_num']),
						'open_time' => (strtotime('2014-01-01 00:00:00')+($ls['open_time'] * 60)),
						'network_id' => $lock['network_id'],
						'network_nums' => $lock['network_nums']
					);
				}
				D('Lockopen')->addLockopenLogAll($data);
				
				$this->ajaxReturn('获取数据成功', 'json');
			}else{
				$this->ajaxReturn('没有新数据', 'json');
			}
		}else{
			$this->ajaxReturn('请输入房间号', 'json');
		}
	}
	
	public function test(){
		$string = 3542334002119028643;
		echo PHP_INT_MAX;
		echo "<br />";
		echo dechex($string). "<br />";
		
	}
	
	private function lrgDec2Hex($number) 
	{ 
		$i = 0; 
		$hex = array(); 

		while($i < 8) { 
			if($number == 0) { 
				array_push($hex, '0'); 
			} 
			else { 
				array_push($hex, strtoupper(dechex(bcmod($number, '16')))); 
				$number = bcdiv($number, '16', 0); 
			} 
			$i++; 
		} 
		krsort($hex); 
		return implode($hex); 
	} 
	
	/**
	 * 请求webservices接口 
	 * @param string $func 接口名称
	 * @param array $param 参数名称
	 **/
	private function CallSoapWebService($func, $param){
		if(is_array($param)){
			if($func == 'GPRSCMD'){
				$param['account'] = 'mmhome';
				$param['md5'] = strtoupper(md5($param['JsonStr'].strtoupper(md5('18002327408'))));
			}else{
				$param['account'] = 'mmhome';
				$param['md5'] = strtoupper(md5('18002327408'));
			}
		}
		
		$client = new \SoapClient($this->webservice);
		try{
			$arr = $client->__call($func, array($func => $param));
			$arr = json_decode(json_encode($arr),true);
			
			if(is_array($arr)){
				switch($func){
					case 'GetNetworkBoxStateByNum':
						
					break;
					case 'GetsOpenRecord': //获取开门日志
						$result = json_decode($arr['GetsOpenRecordResult'], true);
					break;
					case 'GPRSCMD': //控制指令
						$list = $arr['GPRSCMDResult'];
						$result = $this->ext_json_decode($list, true);
					break;
				}
				
				return $result;
			}
		}catch(Exception $e){
			$this->ajaxReturn(0, '读取数据失败');
		}
	}
	
	/**
	 * 解析JSON中没有使用双引号包含的key
	 *
	 **/
	private function ext_json_decode($str, $mode=false){
		if(preg_match('/\w:/', $str)){
			$str = preg_replace('/(\w+):/is', '"$1":', $str);
		}
		$str = str_replace("'", '"', $str);
		return json_decode($str, $mode);
	}
	
	/**
	 * 交换字符串位置
	 *
	 **/
	private function strrevtostr($string){
		if(strlen($string) < 16){
			$string = str_pad(strrev($string), 18, 'F');
			//交换位置
			$newString = "";
			for($i=0;$i<=17;$i++){
				if($i%2 == 0){
					$newString .= $string[$i+1];
				}else{
					$newString .= $string[$i-1];
				}
			}
		}else{
			$newString = str_pad($string, 18, 'F');
		}
		
		return $newString;
	}
	
	
}

